﻿using SmartPlant.Core.Mvvm;
using System.Collections;
using System.Collections.Specialized;
using System.Windows;
using Telerik.Windows.Controls;

namespace SmartPlant.Core.Behavior
{
    /// <summary>
    /// 用于支持MVVM模式下绑定ColumnGroups属性
    /// </summary>
    public class TelerikGroupsBindingBehavior : SmartViewModel
    {
        private readonly RadGridView grid = null;
        private readonly INotifyCollectionChanged _groupColumns = null;

        public static readonly DependencyProperty ColumnGroupsProperty
            = DependencyProperty.RegisterAttached("ColumnGroups", typeof(INotifyCollectionChanged), typeof(TelerikGroupsBindingBehavior),
                new PropertyMetadata(new PropertyChangedCallback(OnColumnGroupsPropertyChanged)));

        public static void SetColumnGroups(DependencyObject dependencyObject, INotifyCollectionChanged columns)
        {
            dependencyObject.SetValue(ColumnGroupsProperty, columns);
        }

        public static INotifyCollectionChanged GetColumnGroups(DependencyObject dependencyObject)
        {
            return (INotifyCollectionChanged)dependencyObject.GetValue(ColumnGroupsProperty);
        }

        private static void OnColumnGroupsPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            var grid = dependencyObject as RadGridView;
            var columns = e.NewValue as INotifyCollectionChanged;

            if (grid != null && columns != null)
            {
                var behavior = new TelerikGroupsBindingBehavior(grid, columns);
                behavior.Attach();
            }
        }

        private void Attach()
        {
            if (grid != null && _groupColumns != null)
            {
                Transfer(GetColumnGroups(grid) as IList, grid.ColumnGroups);

                _groupColumns.CollectionChanged -= ContextColumnGroups_CollectionChanged;
                _groupColumns.CollectionChanged += ContextColumnGroups_CollectionChanged;
            }
        }

        public TelerikGroupsBindingBehavior(RadGridView grid, INotifyCollectionChanged columns)
        {
            this.grid = grid;
            this._groupColumns = columns;
        }

        void ContextColumnGroups_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            UnsubscribeFromEvents();

            Transfer(GetColumnGroups(grid) as IList, grid.ColumnGroups);

            SubscribeToEvents();
        }

        void GridColumnGroups_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            UnsubscribeFromEvents();

            Transfer(grid.ColumnGroups, GetColumnGroups(grid) as IList);

            SubscribeToEvents();
        }

        private void SubscribeToEvents()
        {
            grid.ColumnGroups.CollectionChanged += GridColumnGroups_CollectionChanged;

            if (GetColumnGroups(grid) != null)
            {
                GetColumnGroups(grid).CollectionChanged += ContextColumnGroups_CollectionChanged;
            }
        }

        private void UnsubscribeFromEvents()
        {
            grid.ColumnGroups.CollectionChanged -= GridColumnGroups_CollectionChanged;

            if (GetColumnGroups(grid) != null)
            {
                GetColumnGroups(grid).CollectionChanged -= ContextColumnGroups_CollectionChanged;
            }
        }

        public static void Transfer(IList source, IList target)
        {
            if (source == null || target == null)
                return;

            target.Clear();

            foreach (object o in source)
            {
                target.Add(o);
            }
        }
    }
}
